/**
 * @author gcy[of1518]
 * @date
 * @description 请求工具类
 * @require whatwg-fetch
 */
import 'whatwg-fetch';
import {message} from 'antd';
// import * as auth from './QMAuth';
import {QMConst} from 'qm-ux';
let statusController = {};

// const
const HOST = QMConst.HOST[QMConst.PROJECT.APIHost];


/**
 * 公共请求类
 * @param {Object} param
 */
let QMFetch = (param) => {
    let {host = HOST, url, timeout = 10, quiet = true, method = 'GET', body = {}} = param;
    url = `${(/\/\//gm).test(url) ? url : host + '/' + url}`;

    if (!(/POST/gmi).test(method)) {
        let [a, u, q = '', s = ''] = (/^([^\?]*?)(\?(.*))?$/gm).exec(url),
            search = Object.entries(body).map(o => `${o[0]}=${o[1]}`).join('&');
        url = `${u}${q ? s && '&' : search && '?'}${search}`;
        delete param.body;
    }

    let option = packParam(param);
    return new Promise((resolve, reject) => {
        //请求超时处理
        const timeoutCall = setTimeout(() => {
            message.warning('网络不给力');
            resolve({data: {}, message: '网络不给力', err: new Error('timeout')});
        }, timeout * 1000);
        fetch(url, option)
            .then((res) => {
                if (typeof __DEBUG__ !== 'undefined' && __DEBUG__) console.log(`fetch:url:${url},option${JSON.stringify(option)}`);
                //status
                let _status = parseInt(res.status);
                let func = statusController[_status];
                if (typeof func === 'function') {
                    func.bind(this, res).apply();
                }
                //clear timeout
                clearTimeout(timeoutCall);
                //promise call`
                res.json().then((res) => {
                    // if (!!res.token) {
                    //     auth.load(res.token);
                    // }
                    // let result = packResponse(res) || {};

                    let {errcode, errmsg} = res || {};

                    if (!errcode) {
                        resolve(res);
                    } else {
                        reject(res);
                        if (errcode === 99999) {
                            location.href = QMConst.HOST["v_sso_server"] + "/logout";
                        }
                        if (errcode === 61007) return;
                        if (errcode === 61003) return;
                        if (errcode === 90001) return; // 内测用户
                        message.error({
                                '45015': '用户已取消关注，无法回复',
                                '45028': '当月群发次数已用完',
                                '44004': '内容不能为空',
                                '48005': '该素材已绑定至自动回复或菜单，无法删除'
                            }[errcode] || errmsg);
                    }
                })
            })
            .catch((err) => {
                clearTimeout(timeoutCall);
                message.warning('请求发生错误，请检查您的网络，稍后重试!');
                reject({res: {}, err: err});
            })
    });
};

/**
 * pack param
 * @param {*} param
 */
function packParam(param) {
    delete param['url'];
    delete param['host'];
    delete param['timeout'];
    // let { Platform, SystemId } = QMConst.get('project') || {};
    //default
    let req = {
        method: "GET",
        credentials: 'include',
        mode: 'cors',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }
    };
    if (param.body && ['Object', 'Array'].includes(param.body.constructor.name)) {
        param['body'] = unescape(JSON.stringify(param['body']).replace(/\\u/g, '%u'));
    }
    return Object.assign(req, param)
}

/**
 *
 * pack response
 * @param {Object} res
 */
function packResponse(res) {
    const {message, status} = res || {};
    let response = {};
    switch (status) {
        case 1:
            response = {...res, success: true};
            break;
        case -1:
            message.error(message);
            response = {...res, success: false};
            break;
        case -2:
            response = {...res, success: false};
            break;
        case -4:
            message.error(message);
            response = {...res, success: false};
            break;
        case -5:
            message.error("加班太多,体力跟不上了.(･･;)");
            response = {...res, success: false};
            break;
        default:
            response = {...res, success: false};
            break;
    }
    return response;
}

QMFetch.register = (code, func) => {
    let _code = parseInt(code);
    if (_code) {
        statusController[code] = func;
    }
}

export default QMFetch;